package com.ovopark.firecar.utils

import android.annotation.SuppressLint
import com.google.gson.*
import com.google.gson.reflect.TypeToken
import java.lang.reflect.Type
import java.text.ParseException
import java.text.SimpleDateFormat
import java.util.*

object JsonUtil {
    private var gson: Gson? = null

    /**
     * 将对象转换成json格式
     *
     * @param ts
     * @return
     */
    @JvmStatic
    fun objectToJson(ts: Any?): String? {
        var jsonStr: String? = null
        if (gson != null) {
            jsonStr = gson!!.toJson(ts)
        }
        return jsonStr
    }

    /**
     * 转为Json字符串. {"key":data}
     * @param maps
     * @return
     */
    @JvmStatic
    fun toJSONString(maps: Map<String?, String?>?): String? {
        return objectToJson(maps)
    }

    /**
     * 将对象转换成json格式(并自定义日期格式)
     *
     * @param ts
     * @return
     */
    @SuppressLint("SimpleDateFormat")
    fun objectToJsonDateSerializer(ts: Any?, dateformat: String?): String? {
        var jsonStr: String? = null
        gson = GsonBuilder().registerTypeHierarchyAdapter(
            Date::class.java,
            JsonSerializer<Date?> { src, typeOfSrc, context ->
                val format = SimpleDateFormat(dateformat)
                JsonPrimitive(format.format(src))
            }).setDateFormat(dateformat).create()
        if (gson != null) {
            jsonStr = gson!!.toJson(ts)
        }
        return jsonStr
    }

    /**
     * 将json格式转换成list对象
     *
     * @param jsonStr
     * @return
     */
    fun jsonToList(jsonStr: String?): List<*>? {
        var objList: List<*>? = null
        if (gson != null) {
            val type = object : TypeToken<List<*>?>() {}.type
            objList = gson!!.fromJson(jsonStr, type)
        }
        return objList
    }

    /**
     * 将json格式转换成list对象，并准确指定类型
     *
     * @param jsonStr
     * @param type
     * @return
     */
    fun jsonToList(jsonStr: String?, type: Type?): List<*>? {
        var objList: List<*>? = null
        if (gson != null) {
            objList = gson!!.fromJson(jsonStr, type)
        }
        return objList
    }

    /**
     * 将json格式转换成map对象
     *
     * @param jsonStr
     * @return
     */
    fun jsonToMap(jsonStr: String?): Map<*, *>? {
        var objMap: Map<*, *>? = null
        if (gson != null) {
            val type = object : TypeToken<Map<*, *>?>() {}.type
            objMap = gson!!.fromJson(jsonStr, type)
        }
        return objMap
    }

    /**
     * 将json转换成bean对象
     *
     * @param jsonStr
     * @return
     */
    @JvmStatic
    fun jsonToBean(jsonStr: String?, cl: Class<*>?): Any? {
        var obj: Any? = null
        if (gson != null) {
            obj = gson!!.fromJson(jsonStr, cl)
        }
        return obj
    }

    /**
     * 将json转换成bean对象
     *
     * @param jsonStr
     * @param cl
     * @return
     */
    @SuppressLint("SimpleDateFormat")
    fun <T> jsonToBeanDateSerializer(jsonStr: String?, cl: Class<T>?, pattern: String?): T? {
        var obj: Any? = null
        gson = GsonBuilder().registerTypeAdapter(
            Date::class.java,
            JsonDeserializer { json, typeOfT, context ->
                val format = SimpleDateFormat(pattern)
                val dateStr = json.asString
                try {
                    return@JsonDeserializer format.parse(dateStr)
                } catch (e: ParseException) {
                    e.printStackTrace()
                }
                null
            }).setDateFormat(pattern).create()
        if (gson != null) {
            obj = gson!!.fromJson(jsonStr, cl)
        }
        return obj as T?
    }

    /**
     * 根据
     *
     * @param jsonStr
     * @param key
     * @return
     */
    fun getJsonValue(jsonStr: String?, key: String?): Any? {
        var rulsObj: Any? = null
        val rulsMap = jsonToMap(jsonStr)
        if (rulsMap != null && rulsMap.size > 0) {
            rulsObj = rulsMap[key]
        }
        return rulsObj
    }

    /**
     * 字符串转 map
     * @param s
     * @return
     */
    fun json2Map(s: String?): Map<String?, String?>? {
        var res: Map<String?, String?>? = null
        try {
            val gson = Gson()
            res = gson.fromJson(s, object : TypeToken<Map<String?, String?>?>() {}.type)
        } catch (e: JsonSyntaxException) {
        }
        return res
    }

    init {
        if (gson == null) {
            gson = Gson()
        }
    }
}